//package com.mrzhou.rabbit.service.impl;
//
//import com.baomidou.mybatisplus.core.metadata.IPage;
//import com.baomidou.mybatisplus.core.toolkit.IdWorker;
//import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
//import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
//import com.fasterxml.jackson.databind.ser.Serializers;
//import com.mrzhou.common.util.VirtualUserUtil;
//import com.mrzhou.core.tool.utils.JacksonUtil;
//import com.mrzhou.mybatis.base.PageQuery;
//import com.mrzhou.rabbit.constant.RabbitConstant;
//import com.mrzhou.rabbit.entity.BaseEsEntity;
//import com.mrzhou.rabbit.entity.EsMqMessage;
//import com.mrzhou.rabbit.entity.User;
//import com.mrzhou.rabbit.mapper.UserMapper;
//import com.mrzhou.rabbit.producer.ElasticsearchProduct;
//import com.mrzhou.rabbit.repository.UserRepository;
//import com.mrzhou.rabbit.service.IUserService;
//import org.elasticsearch.client.RestHighLevelClient;
//import org.elasticsearch.index.query.DisMaxQueryBuilder;
//import org.elasticsearch.index.query.MatchQueryBuilder;
//import org.elasticsearch.index.query.QueryBuilder;
//import org.elasticsearch.index.query.QueryBuilders;
//import org.elasticsearch.index.reindex.UpdateByQueryRequestBuilder;
//import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
//import org.elasticsearch.search.sort.ScoreSortBuilder;
//import org.elasticsearch.search.sort.SortOrder;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.beans.factory.annotation.Qualifier;
//import org.springframework.data.domain.PageRequest;
//import org.springframework.data.domain.Pageable;
//import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
//import org.springframework.data.elasticsearch.core.SearchHit;
//import org.springframework.data.elasticsearch.core.SearchHits;
//import org.springframework.data.elasticsearch.core.document.Document;
//import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
//import org.springframework.data.elasticsearch.core.query.*;
//import org.springframework.stereotype.Service;
//
//import java.time.LocalDateTime;
//import java.util.ArrayList;
//import java.util.List;
//import java.util.Map;
//import java.util.concurrent.Executor;
//import java.util.stream.Collectors;
//
///**
// * @author qiang.zhou
// */
//@Service
//public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
//
//    private final Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
//
//    @Autowired
//    @Qualifier("INSERT_USER_EXECUTOR")
//    private Executor executor;
//    @Autowired
//    private ElasticsearchProduct elasticsearchProduct;
//    @Autowired
//    private ElasticsearchRestTemplate elasticsearchRestTemplate;
//    @Autowired
//    private UserRepository userRepository;
//
//    @Override
//    public int insertVirtualUser(int loop, int limit) {
//        long startTime = System.currentTimeMillis();
//        while (loop > 0) {
//            loop--;
//            List<User> list = new ArrayList<>();
//            LocalDateTime now = LocalDateTime.now();
//            for(int i = limit; i > 0; i--) {
//                User user = new User();
//                Long id = IdWorker.getId();
//                user.setId(id);
//                user.setName(VirtualUserUtil.randName(2));
//                user.setValue(VirtualUserUtil.randName(2));
//                user.setSex(VirtualUserUtil.random(0, 2));
//                user.setBirthday(VirtualUserUtil.timeToLocalDate(VirtualUserUtil.randDate ("1970-03-01 00:00:00", "2010-03-01 23:59:59")));
//                user.setStatus(0);
//                user.setIsDelete(1);
//                user.setCreateUser(id);
//                user.setCreateTime(now);
//                user.setCreateUser(id);
//                user.setUpdateUser(id);
//                user.setUpdateTime(now);
//                user.setExtendData(JacksonUtil.toJsonString(user));
//                list.add(user);
//                // 发送至消息队列
//                handlerUser(user);
//            }
//            // 将批量插入任务提交至线程池执行
//            executor.execute(() -> baseMapper.insertBatch(list));
//        }
//        logger.info("\n花费时间：" + (System.currentTimeMillis() - startTime));
//        return 0;
//    }
//
//    private void handlerUser(User user) {
//        EsMqMessage<User> message = new EsMqMessage();
//        message.setId(user.getId());
//        message.setAction(EsMqMessage.CREATE_OR_UPDATE);
//        message.setData(user);
//        elasticsearchProduct.send(message);
//    }
//
//    public void updateUser() {
//        IndexCoordinates indexCoordinates = elasticsearchRestTemplate.getIndexCoordinatesFor(User.class);
//        Document document = Document.create();
//        document.put("value", "易智文");
//        elasticsearchRestTemplate.update(UpdateQuery.builder("1391686695799054356").withDocument(document).build(), indexCoordinates).getResult();
//        elasticsearchRestTemplate.indexOps(indexCoordinates).refresh();
//    }
//
//    /**
//     *  基础查询示例
//     * @param name
//     * @return
//     */
//    @Override
//    public IPage<User> getElasticsearchUserByName(String name, Integer current, Integer size) {
//        NativeSearchQuery nativeSearchQuery=new NativeSearchQueryBuilder()
//                .withQuery(QueryBuilders.matchQuery("name", name).boost(2F))
//                .build();
//        SearchHits<User> hits = elasticsearchRestTemplate.search(nativeSearchQuery, User.class);
//        List<User> users = new ArrayList<>();
//        hits.stream().forEach(var -> users.add(var.getContent()));
//        IPage<User> pages = new Page<>(current, size, hits.getTotalHits());
//        return pages.setRecords(users);
//    }
//
//    /**
//     * matchQuery       : 单个字段查询
//     * matchAllQuery    : 匹配所有
//     * multiMatchQuery  : 多个字段匹配某一个值
//     * wildcardQuery    : 模糊查询
//     * boost            : 设置权重,数值越大权重越大
//     * 混合搜索
//     * @param name 搜索的关键字
//     * @param page 分页查询对象
//     * @return
//     */
//    @Override
//    public IPage<User> pageSearchUser(String name,  PageQuery page) {
//        DisMaxQueryBuilder queryBuilder = QueryBuilders.disMaxQuery();
//        QueryBuilder ikTypeQuery = QueryBuilders.matchQuery("name", name).boost(2F);
//        queryBuilder.add(ikTypeQuery);
//        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(queryBuilder).withPageable(PageRequest.of(page.getPage(), page.getSize())).build();
//        SearchHits<User> hits = elasticsearchRestTemplate.search(searchQuery, User.class);
//        IPage<User> pages = new Page<>(page.getCurrent(), page.getSize(), hits.getTotalHits());
//        return pages.setRecords(hits.stream().map(SearchHit::getContent).collect(Collectors.toList()));
//    }
//
//    @Override
//    public IPage<User> highlightSearchUser(String value,  PageQuery page) {
//        updateUser();
//
//        DisMaxQueryBuilder queryBuilder = QueryBuilders.disMaxQuery();
//        QueryBuilder pinyinTypeQuery = QueryBuilders.matchQuery("value", value);
//        queryBuilder.add(pinyinTypeQuery);
//
//        // 汇总查询条件
//        queryBuilder.add(pinyinTypeQuery);
//        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
//                .withQuery(queryBuilder)
//                .withSort(new ScoreSortBuilder().order(SortOrder.DESC))
//                .withPageable(PageRequest.of(page.getPage(), page.getSize()))
//                .withHighlightFields(new HighlightBuilder.Field("value")) // 高亮查询的字段
//                .withHighlightBuilder(new HighlightBuilder().preTags(RabbitConstant.HIGH_LIGHT_START_TAG).postTags(RabbitConstant.HIGH_LIGHT_END_TAG)) // 关键字高亮前后标签
//                .build();
//        // 查询结果
//        SearchHits<User> hits = elasticsearchRestTemplate.search(searchQuery, User.class);
//
//
//        IPage<User> pages = new Page<>(page.getCurrent(), page.getSize(), hits.getTotalHits());
//        return pages.setRecords(hits.stream().map(var -> {
//            Map<String, List<String>> hi = var.getHighlightFields();
//            User user = var.getContent();
//            user.setValue(hi.get("value").get(0));
//            return user;
//        }).collect(Collectors.toList()));
//    }
//
//    @Override
//    public void bulkElasticsearch(int loop, int limit) {
//        long startTime = System.currentTimeMillis();
//        while (loop > 0) {
//            loop--;
//            List<IndexQuery> list = new ArrayList<>();
//            LocalDateTime now = LocalDateTime.now();
//            for(int i = limit; i > 0; i--) {
//                User user = new User();
//                Long id = IdWorker.getId();
//                user.setId(id);
//                user.setName(VirtualUserUtil.randName(2));
//                user.setValue(VirtualUserUtil.randName(2));
//                user.setSex(VirtualUserUtil.random(0, 2));
//                user.setBirthday(VirtualUserUtil.timeToLocalDate(VirtualUserUtil.randDate ("1970-03-01 00:00:00", "2010-03-01 23:59:59")));
//                user.setStatus(0);
//                user.setIsDelete(1);
//                user.setCreateUser(id);
//                user.setCreateTime(now);
//                user.setCreateUser(id);
//                user.setUpdateUser(id);
//                user.setUpdateTime(now);
//                user.setExtendData(JacksonUtil.toJsonString(user));
//
//                IndexQuery indexQuery = new IndexQuery();
//                indexQuery.setId(String.valueOf(id));
//                indexQuery.setObject(user);
//                list.add(indexQuery);
//            }
//            // 将批量插入任务提交至线程池执行
//            executor.execute(() -> {
//                IndexCoordinates indexCoordinates = elasticsearchRestTemplate.getIndexCoordinatesFor(User.class);
//                elasticsearchRestTemplate.bulkIndex(list, indexCoordinates);
//            });
//        }
//        logger.info("\n花费时间：" + (System.currentTimeMillis() - startTime));
//    }
//
//    public <T extends BaseEsEntity> void bulk(List<T> entity, Class<T> clazz) {
//        IndexCoordinates indexCoordinates = elasticsearchRestTemplate.getIndexCoordinatesFor(clazz);
//        List<IndexQuery> datas = entity.stream().map(var -> {
//            IndexQuery indexQuery = new IndexQuery();
//            indexQuery.setId(String.valueOf(var.getId()));
//            indexQuery.setSource(JacksonUtil.toJsonString(var));
//            return indexQuery;
//        }).collect(Collectors.toList());
//        elasticsearchRestTemplate.bulkIndex(datas, indexCoordinates);
//    }
//
//
//}
